perm filename A07.TEX[106,RWF] blob
sn#827992 filedate 1986-11-10 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 \magnification\magstephalf
C00056 ENDMK
C⊗;
\magnification\magstephalf
\input macro.tex
\def\today{\ifcase\month\or
January\or February\or March\or April\or May\or June\or
July\or August\or September\or October\or November\or December\fi
\space\number\day, \number\year}
\baselineskip 14pt
\rm
\line{\sevenrm a07.tex[106,phy] \today\hfill}
\font\rmn=cmr9
\bigskip
\line{{\bf Files.} (Assumes Strings) [RWF: needs rewriting]\hfil}
A file is a sequence of characters or data. Because it is
typically stored in
magnetic disc memory, it is permanent and there is room for it to be very
long, but (unlike an array) it can only be created or used in a fixed
left-to-right order. A file may be read or written by a program. At any
given moment, a~file can be in one of three conditions (called modes):
closed, open for reading, open for writing. There is a family of
operations, called input operations, that can only be done on a file that
is open for reading. The input operations bring information from the file
into the program. There is another family of operations, called output
operations, which can only be done on a file that is open for writing.
Opening a file for writing
is a bit like checking a book out of the library; nobody
else can use the file while you have it open, and it must eventually be
closed again.
A file in Pascal has two names; an internal name, by which it is called
inside the Pascal program, and an external name, by which it is stored in
the computer's directory, and which is
used in editing and other executive operations.
Usually, a Pascal implementation allows the user to specify an external name
for each internal name; this allows a single Pascal program to
be applied to many different files. The relation between internal and
external names is closely analogous to the relation between parameters and
arguments.
In the definitions and examples that follow, we shall use {\tt IN} as
exemplifying the internal name of a file which has been opened for
reading, {\tt OUT} as the internal name of a file which has been opened for
writing, and {\tt ANY} as a typical internal name of a file in any mode. We
shall use {\tt INX}, {\tt OUTX},
and {\tt ANYX} in the same way as the corresponding
external names. We shall use {\tt I}, {\tt R},
{\tt C}, and~{\tt B} as typical variables of types
{\tt INTEGER}, {\tt REAL}, {\tt CHAR}, and {\tt BOOLEAN}.
If a certain file is a sequence of components $e↓1 e↓2 e↓3\ldots e↓n$, and is open
for reading, there is always a mark, akin to a bookmark, separating the
part of the file that has already been read from the part that has not.
In our examples, we use @ as the read mark and
to show that the file is open for reading. When the file
is first opened for reading, it looks like $@e↓1 e↓2 e↓3\ldots e↓n$. When
all the components of the file have been read, the file looks like
$e↓1 e↓2 e↓3\ldots e↓n@$, which is
the end-of-file condition for that file.
If a file is open
for writing, we show this by including a similar write mark,~\#. All
writing is done at the right end of the file, so a file open for writing
initially looks like just~\#, and later looks like $e↓1 e↓2 e↓3\ldots e↓n\#$.
The files {\tt INPUT} and {\tt OUTPUT}, if used, are automatically opened
for reading and writing respectively. Their use may be [?] limited to those
modes.
The components of a file may be of any one type, except that files may not
be parts of other files. Common are files of integers, real numbers, and
Boolean values. Most common of all, though, are the files used to
represent text laid out in lines on pages, called text files. Many of
Pascal's operations are defined exclusively for text files. The files
{\tt INPUT} and {\tt OUTPUT} are automatically text files.
The components of a text file are a mixture of characters with other
symbols, principally an end-of-line symbol. [Check standard.]
The Pascal Standard also
allows an implementation to have a way to represent the end of a page
in a text file, but does not specify details. The end-of-line symbol,
which we shall call $\eol$, divides the characters of the text file into
lines, which in practice must be short enough for printing and viewing.
A~completed text file must end with an $\eol$, which Pascal automatically
provides under some conditions.
If a text file {\tt OUT} is in write mode, the statement
{\tt WRITE(OUT,X)}, where {\tt X} is a {\tt REAL}, {\tt INTEGER},
{\tt BOOLEAN}, or string expression, expresses
{\tt X} as a string of characters and appends it to the file at the end.
(For format details, see \_\_\_ .) The statement {\tt WRITELN(OUT)}
appends $\eol$ to the file. Useful built-in abbreviations are
{\tt WRITE(OUT,X$↓1$,...,X$↓n$)} for
{\obeylines\obeyspaces\let =\ \tt
BEGIN WRITE(OUT,X$↓1$); $\ldots$ WRITE(OUT,X$↓n$); END
}
\noindent
and {\tt WRITELN(OUT,X$↓1$,...,X$↓n$)} for
{\obeylines\obeyspaces\let =\ \tt
BEGIN WRITE(OUT,X$↓1$); $\ldots$ WRITE(OUT,X$↓n$); WRITELN END
}
\noindent
If the file involved is {\tt OUTPUT}, the above operations can be abbreviated
to {\tt WRITE(X)}, {\tt WRITELN}, {\tt WRITE(X$↓1$,...,X$↓n$)}, and
{\tt WRITELN(X$↓1$,...,X$↓n$)}. That is, {\tt OUTPUT} is the default
file for writing. It is therefore convenient to use {\tt OUTPUT} as the
main file to which a program writes.
Output text files for printing should be limited to the width of the printer,
typically
132 characters; that is, your program should execute {\tt WRITELN} before
writing more than 132 characters. At most 60~lines will typically
fit on a page;
the command {\tt PAGE(OUT)} can be used to start at the beginning of a new
page, even if the old one is not full. (If {\tt PAGE} is not used, a new page
will be started whenever a page fills up.) [Check standard.]
Similarly, output to be viewed on
a typical terminal screen
should be at most 80~characters wide and (if you want it all to be visible
at once) 24~lines high.
If a text file {\tt IN} is in {\tt READ} mode, the statement {\tt READ(IN,X)}
takes from the file a value of {\tt REAL}, {\tt INTEGER}, or {\tt CHAR} type
and assigns it to the variable~{\tt X}, which must be suitable. If {\tt X}~is
of a numerical type, the statement skips over initial blanks (i.e.,
{\tt \spa} and $\eol$), reads the characters of a numerical value, and stops
when the next character could not belong to that value, without passing over
that character. For example, the file goes from
{\tt ABC@$\eol${\spa}123.4{\spa}$\eol$} to
{\tt ABC$\eol${\spa}123.4@{\spa}$\eol$}.
If {\tt X} is of type {\tt CHAR}, the statement treats $\eol$ as if it
were~{\tt\spa}, so programs can distinguish $\eol$ from {\tt\spa} on files
only by explicitly testing for $\eol$. It is an error to execute a {\tt READ}
statement unless the file contains an unread value of the required type.
The statement {\tt READLN(IN)} moves the read mark past the next
$\eol$, changing\break
{\tt ABC@DE$\eol$FG$\eol$} to
{\tt ABCDE$\eol$@FG$\eol$}.
It is an error in an end-of-file condition.
Useful built-in abbreviations are {\tt READ(IN,X$↓1$,...,X$↓n$)}
for
{\obeylines\obeyspaces\let =\ \tt
BEGIN READ(IN,X$↓1$); $\ldots$ READ(IN,X$↓n$) END
}
%\vfil\eject
\noindent
and {\tt READLN(IN,X$↓1$,...,X$↓n$)} for
{\obeylines\obeyspaces\let =\ \tt
BEGIN READ(IN,X$↓1$); $\ldots$ READ(IN,X$↓n$) READLN(IN) END
}
The end-of-file
condition {\tt EOF(IN)} is true if the read mark is at the end of
the file. No other input operation is allowed when {\tt EOF} is true,
so if an end-of-file condition is possible, a~program should check
by {\tt EOF} first.
The end-of-line
condition {\tt EOLN(IN)} is true if the read mark is followed by $\eol$,
false if it is followed by any other symbol, and an error at the end
of file. It is the only way to distinguish $\eol$ from {\tt\spa} on an
input file.
If the file involved is {\tt INPUT}, the above operations can be abbreviated
to {\tt READ(X)}, {\tt READLN}, {\tt READ(X$↓1$,...,X$↓n$)},
{\tt READLN(X$↓1$,...,X$↓n$)}, {\tt EOF}, and {\tt EOLN}. That is,
{\tt INPUT} is the default file for reading. It is therefore convenient
to use {\tt INPUT} as the main file from which a program reads.
\bigskip
\line{\bf Non-Text Files \hfil}
If a file is not of type {\tt TEXT}, it can hold values only of one single type.
Say {\tt ANY} is a file of integers. Then integer values
can be
written on it by {\tt WRITE(ANY,I$↓1$,I$↓2$)}
when it is open for writing. When
it is open for reading, values can be read from it to integer variables
by {\tt READ(ANY,I$↓1$,I$↓2$)}.
An end-of-file condition can be tested by
{\tt EOF(ANY)}. No other input or output operations can be done. Similar
restrictions apply to files of real, boolean, or character values. Files
of integer, real, and boolean values may not be in a form suitable for
printing or for reading on a terminal screen; they are used primarily
for communication between programs, or between successive stages of a
single program.
\bigskip
\line{\bf Files in General.\hfil}
All files in Pascal except {\tt INPUT} and {\tt OUTPUT}
must be declared as variables,
of type either {\tt TEXT} or {\tt FILE OF t}, where {\tt t}~is
any type not itself
containing files. [Repetitive.]
(For example, {\tt FILE OF REAL} and
{\tt FILE OF ARRAY [1..10] OF CHAR}.)
The names {\tt INPUT} and {\tt OUTPUT} are implicitly declared of type
{\tt TEXT}, and should not be declared as variables.
Some files are used entirely within a single program; they are written by
that program, later are read during the same execution, and are then no
longer needed. Such {\it internal\/} files do not need an external name. Input
files which provide data to the program from the user or some other
external source, and output files for printing or other subsequent use,
must have an external name. Such {\it external\/} files must be listed in the
program header line. The header is of the form
{\obeylines\obeyspaces\let =\ \tt
PROGRAM P(ANY1,ANY2,ANY3);
}
\noindent
where all internal names of external files are listed (including {\tt INPUT}
and {\tt OUTPUT} if they are used). When the program is executed, the
user will be asked for the external name corresponding to
each internal name.
A file may be opened for reading by the command {\tt RESET(ANY)}. It may be
opened for writing by the command {\tt REWRITE(ANY)}.
At the end of a Pascal program, all its files are
automatically closed. At the beginning of a Pascal program, the files
{\tt INPUT} and {\tt OUTPUT} are automatically and permanently
opened for reading and writing
respectively. Other files must be opened explicitly before any input or
output operations can be executed.
It is possible for the program to ``see'' the next single element on
a file without actually moving the read pointer; if the file's internal
name is {\tt IN}, and the file contains $e↓1 e↓2\ldots e↓{i-1}@e↓i\ldots e↓n$,
the
expression {\tt IN$\uparrow$} (or {\tt IN$\wedge$}
on some keyboards) has the value~$e↓i$; to
discard characters from a text file up to but not including the next space,
for example, one could do
{\obeylines\obeyspaces\let =\ \tt
WHILE IN$\uparrow$<>'{\spa}' DO READ(IN,C).
}
\noindent
The read pointer can be moved one place to the right without reading, by
the command {\tt GET(IN)}. In fact, {\tt READ(IN,C)}
is an abbreviation for
{\tt C:=IN$\uparrow$; GET(IN)}. The above example, then, could also be
{\obeylines\obeyspaces\let =\ \tt
WHILE IN$\uparrow$<>'\spa'DO GET(IN).
}
\noindent
It is, of course, an error to execute {\tt GET(f)} when file~{\tt f} is
exhausted.
[Add section on {\tt PUT}?]
\vfill\eject
%\bigskip
\line{\bf File Cliches.\hfil}
To read and process every component of a non-text file, or every character of a
text file, with subalgorithms to
initialize before the first and finish after the
last, the standard pattern in Pascal is:
{\obeylines\obeyspaces\let =\ \tt
BEGIN
RESET(f);(* not needed initially if f is INPUT *)
initialize;
WHILE NOT EOF(f) DO
BEGIN
READ(f,x);
process datum in x
END;
(* all data processed, at end of file *)
finish
END
}
Suppose I have a file containing numerical data, interspersed with spaces.
I~want to process each number, perhaps by adding it to a running total.
When the file is exhausted, I~want to finish up, perhaps by printing the
total. Here are two plausible programs that don't work.
{\obeylines\obeyspaces\let =\ \tt
BEGIN
initialize;
WHILE NOT EOF DO
BEGIN
READ(X);
PROCESS X
END;
finish
END
}
\noindent
The program above always fails. After reading the last number, the read mark
is still to the left of at least one character (the final $\eol$), so
{\tt EOF} is still false. Another {\tt READ(X)} is executed, the program
looks for a nonexistent number, and an error stop results. Another
solution, popular because it sometimes works:
{\obeylines\obeyspaces\let =\ \tt
BEGIN
initialize;
WHILE NOT EOF DO
BEGIN
READLN(X);
PROCESS X
END;
finish
}
\noindent
It fails when there is more than one number on a line, by ignoring all but
the first. It also fails unless the last datum is on the last line.
It would ail in both ways on the file:
{\obeylines\obeyspaces\let =\ \tt
{\spa}12.3{\spa}{\spa}45.678{\spa}{$\eol$}{\spa}{\spa}{$\eol$}
}
\noindent
Printing the data files shows the first difficulty, if the reader knows
to look for it, but the second is invisible.
Observe that it is never safe to execute {\tt READLN(X)}, because there
might be more than one number in the current line. It is never safe to
execute {\tt READ(X)} unless {\tt INPUT}$\uparrow$ is non-blank, because
there might be no more numbers. It is almost never safe to do any input
operation without first checking {\tt EOF}, because the read mark might
be at the end of the file already. We organize the algorithm to do only
what is safe.
On each entry to the iteration, {\tt EOF} is tested. If true, the
iteration is finished; if false, {\tt INPUT}$\uparrow$ may be tested. Inside
the iteration, {\tt INPUT}$\uparrow$ is tested. If it is a space
(or $\eol$ masquerading as a space), it is safe to discard one input
character. If it is not a space, it must be part of a number, and it is
safe to read that number. The solution:
{\obeylines\obeyspaces\let =\ \tt
BEGIN
initialize;
WHILE NOT EOF DO
IF INPUT$\uparrow$='{\spa}') THEN GET(INPUT)
ELSE
BEGIN
READ(X);
process X
END;
finish
END
}
%\vfill\eject
An alternate method uses a sentinel in the file to mark the end of
the data. A~sentinel is a special value, like 999999, of the same type as
the data, that can be read by the same {\tt READ} that reads the data.
{\obeylines\obeyspaces\let =\ \tt
BEGIN
(* RESET(f) if needed *)
initialize;
READ(f,X);
WHILE(X is not a sentinel) DO
BEGIN
process X;
READ(f,X)
END;
(* RESET(f) if needed *)
finish
END
}
\noindent
The above program is more efficient, needing only one test per iteration.
Its structure seems rather peculiar; each iteration processes the number
read on the previous iteration. Only this way can the sentinel be read
without being processed.
%\vfill\eject
To process one line of characters on a text file, assuming that
a~line of data is known to be next on~{\tt f}, so no preliminary
{\tt EOF} test is needed:
{\obeylines\obeyspaces\let =\ \tt
BEGIN
initialize;
WHILE NOT EOLN(f) DO
BEGIN
READ(f,C);
process C
END;
(* next character is end-of-line *)
READ(f,C); (* or GET(f) or READLN(f) *)
finish
END
}
To process every line of characters in a text file, with subalgorithms~{\tt A}
initializing the whole computation, {\tt B}~initializing the processing
of one line, {\tt D}~finishing the processing of one line, and
{\tt E}~finishing the whole computation:
{\obeylines\obeyspaces\let =\ \tt
BEGIN
A;
(* reset(f) if needed *)
WHILE NOT EOF(f) DO
(* process one line *)
BEGIN
B;
WHILE NOT EOLN(f) DO
BEGIN
READ(f,C);
process C
END;
READ(f,C);(* discard end-of-line symbol *)
D
END;
(* end of file *)
E
END
}
\vfill\eject
{\rmn
{\narrower\smallskip\noindent
{\bf Example:} a program to test that every line of file {\tt f} contains at least
one asterisk:
{\obeylines\obeyspaces\let =\ \tt
BEGIN
(* RESET(f) if needed *)
EVERYLINE:=TRUE; (* Until line with no asterisk *)
WHILE NOT EOF(f) DO
BEGIN
THISLINE:=FALSE; (* Until asterisk on current line *)
WHILE NOT EOLN(f) DO
BEGIN
READ(f,C);
IF C='*' THEN
THISLINE:= TRUE
END;
READ(f,C);
IF NOT THISLINE THEN
EVERYLINE:=FALSE
END;
IF EVERYLINE THEN WRITE('EVERY LINE HAS A STAR')
ELSE WRITE ('NOT EVERY LINE HAS A STAR')
(* RESET(f) if needed *)
END
}
\smallskip}
}
\vfill\eject
{\rmn
{\narrower\smallskip\noindent
{\bf Example:} Program to read a text file, and left-justify it with as many
words as possible on a line. The original line breaks are ignored.
[RWF: Debug this and comment on it]
{\obeylines\obeyspaces\let =\ \tt
BEGIN PROGRAM(---);
Declarations;
PROCEDURE PROCESS (X: CHAR);
BEGIN
IF X <> '{\spa}' THEN
BEGIN
LETCOUNT:= LETCOUNT+1; (* WORD LENGTH *)
WORD [LETCOUNT]:=X
END
ELSE
BEGIN
IF LINELENGTH+LETCOUNT+1>LIMIT THEN
BEGIN
WRITELN;
LINELENGTH:=0
END;
IF LINELENGTH>0 THEN
BEGIN
WRITE (' ');
LINELENGTH:=LINELENGTH+1+LETCOUNT
END
ELSE LINELENGTH:=LETCOUNT;
FOR I:=1 TO LETCOUNT DO
WRITE(WORD [I])
LETCOUNT:=0
END
END;
BEGIN (* MAIN PROGRAM *)
LETCOUNT:=0;
LINELENGTH:=0;
LASTC:= '{\spa}';
WHILE NOT EOF DO
BEGIN
READ(C);
IF (LASTC <> '{\spa}' ) OR (C<> '{\spa}' ) THEN
PROCESS(C);
LASTC:=C
END;
(* RESET if needed *)
END
}
If running time is important, the call on {\tt PROCESS(C)} can be
replaced by a slightly modified copy of the procedure body. The program
uses the fact that {\tt READ} treats the end-of-line symbol as a space.
\smallskip}
}
\bigskip
\line{\bf Interactive Computing [Explain buffer]\hfil}
Pascal was designed before 1974 for use on computers that took input from
already completed files, and wrote results on files that were not seen by
people until they were complete. Many current computers, however, accomodate
programs that ``converse'' with their users. The computer may display
information on a viewing screen, ask questions, and accept answers as they
are typed by a human user. Examples of such programs are word processing
programs, video games, personal filing systems, and computer aided
instruction.
Most Pascal implementations on interactive computers use non-standard
and non-uniform features to communicate with the user interactively.
In this text, we will use these operations:
\smallskip
\display 25pt:$\bullet$:
{\tt WRITESCREEN(X)} displays the value of~{\tt X} on the viewing screen.
\smallskip
\display 25pt:$\bullet$:
{\tt WRITELNSCREEN} terminates a line on the viewing screen.
\smallskip
\display 25pt:$\bullet$:
{\tt READKEYS(X)} accepts a value of~{\tt X} from the user's keyboard.
\smallskip
\display 25pt:$\bullet$:
{\tt EOLNKEYS} is true if the next input symbol from the user's keyboard
is the end-of-line (carriage return) symbol.
\smallskip
\display 25pt:$\bullet$:
{\tt EOFKEYS} is true if the next input symbol from the user's keyboard
is an end-of-file symbol.
\smallskip
[Need {\tt READLNKEYS}]
\smallskip
Appendix \_\_\_ shows how the above operations are done in several widely
used Pascal implementations. In a~course, the instructor should provide
replacements for each of the above operations.
\bigskip
\line{{\bf Pseudo-files.} [Non-standard, Stanford only] [Incorrect about modes]\hfil}
Pascal treats several entities more or less as if they were files. The
external name {\tt TTY:} (note the colon) can be used to let the corresponding
internal name represent data typed at the terminal keyboard when in read
mode, and represent the terminal screen when in write mode. In write
mode, this is sometimes useful to see the results of a program immediately
as it writes them, especially if the lines of output are no more than the
80-character width of the screen. In read mode, the use of external name
{\tt TTY:} can not be recommended; a program designed for input from a true
file is usually not well designed for keyboard input. See \_\_\_
for details.
The internal name {\tt TTY} can also be used to represent the terminal keyboard
and screen. Output commands to {\tt TTY}, such as
{\tt WRITE(TTY,X1,X2)}, are quite
analogous to output commands for files. Input commands, however, differ.
During the execution of a Pascal program, the sequence of characters typed
at the keyboard is used as if it were a text file called {\tt TTY} for all input
operations. A line typed in is made available to the program only when it
is completed with a carriage return; up until entry of the carriage return
the user may modify the line at will, for example by backspacing. When
the program has consumed all available keyboard input, it stops and waits
until the user has typed another complete line. To avoid impasses, a
program should request more input before consuming all available input
characters (in particular, the final carriage return). The pseudo-file
with internal name {\tt TTY} is automatically
initialized to an empty line, as if a single
carriage return had already been typed in, so that the program can
continue execution (Older versions of the translator required
at least an $\eol$ from the
keyboard
before the program would start). The pseudo-file {\tt TTY} is not
mentioned in the program header, nor is it declared. It is treated as of
type {\tt TEXT}. For input pseudo-files {\tt TTY} or {\tt TTY:},
an end-of-file condition is
created only by typing {\tt CONTROL/Z}; usually programs intended for
terminal input do not use the end-of-file condition.
The external name {\tt LPT:} ( note the colon) can be used as a pseudo-file, in
write mode, for information which is to be printed automatically upon completion
of execution, and is not to be retained as a permanent file.
\bigskip
\noindent
{\bf Terminal Input Cliches.} [RWF: relocate] [Give Stanford equivalents] [Show
numbers too]
Reading data as lines of characters from the terminal is typically done by
the subprogram below.
{\obeylines\obeyspaces\let =\ \tt
BEGIN
INITIALIZE;
WRITESCREEN(prompting message);
(* Explain to the user what he must type *)
READLNKEYS;
(* discard remnants of previous line; program waits here
until user completes a new line *)
WHILE NOT EOLNKEYS DO
BEGIN
READKEYS(C);
Process C
END;
Process carriage return, if required, without reading it.
END
}
Alternatively, [non-standard]
a line can be read into a string variable~{\tt S},
of type {\tt PACKED}
{\tt ARRAY[1..80] OF CHAR}; the subprogram below tests each line for validity and
reads again until an acceptable line has been read.
\vfill\eject
{\obeylines\obeyspaces\let =\ \tt
BEGIN
WRITESCREEN(prompting message);
BADDATA:=TRUE;
WHILE BADDATA DO
BEGIN
READLNKEYS;
(* Discard remnants of earlier line *)
READKEYS(S);
(* Puts in S the entire line except carriage return *)
IF(S is acceptable) THEN
BADDATA:=FALSE
ELSE
WRITESCREEN(reprompting message)
(* Explain exact requirements for correct input *)
END
END
}
\bigskip
\line{{\bf The Naming of Files.} [Non-standard]\hfil}
Like the naming of cats [1], the naming of files should not be undertaken
lightly. See the section of the LOTS Overview on file descriptors [ ] for
the rules about directory names. The extension field of your program
should normally be {\tt PGO}, for translation by the {\tt PASSGO}
translator. If your
program uses a separate library of subprograms, use the {\tt PASCAL} translator
by making {\tt PAS} the extension field. The file name proper of your program
for a course assignment should begin with an identification of the
assignment number. A~program for assignment~8, to do an integration,
might be in file {\tt P8INT.PGO}. The data file for a program should have the
same name except for extension field {\tt DAT} (e.g., {\tt P8INT.DAT});
the output
file should have the same name except for extension field {\tt OUT} (e.g.,
{\tt P8INT.OUT}). An interactive program should keep a permanent record of all
input, perhaps on a file with extension field {\tt LOG}; this allows later
confirmation that data were entered correctly.
It is a common disastrous error to give the name of the program as the
external name of the output file; this results in deletion of the program
file. When this happens, (1) DO NOT LOGOUT, (2) DO NOT EXPUNGE, until
the deleted file has been recovered. See Overview for
methods to locate and restore deleted files. As a safety measure, you can
set the normal number of file generations retained in your directory to~2.
(E.g., if your program is in file {\tt P8INT.PGO.10}, and you send output to
{\tt P8INT.PGO}, it will go to {\tt P8INT.PGO.11},
and generations~10 and~11 will
both be retained.) If you do so, you should delete all obsolete files
at the end of each terminal session.
\bigskip
\line{{\bf Test Files.} [Move to section on testing.]\hfil}
In testing a program which will use a large data file, such as a dictionary
for a spelling checker program, use a much smaller test file, for several
reasons:
\disleft 25pt:(1):
Your testing will take less time.
\disleft 25pt:(2):
You will be able to predict exactly what the program should do.
\disleft 25pt:(3):
You can easily change the file to exercise all parts of the program.
(Long words, words which come after the last dictionary entry, ... .)
\bigskip
\line{\copyright 1983 Robert W. Floyd.\hfil}
%First draft (not published) ??\hfil}
%revised: Date; subsequently revised.\hfill}
\bye